package com.bsdsma.fengheguaiapp.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.*;

@Slf4j
public class CustomerBeanUtils {

    private static final String STATUS_FIELD = "status";


    public static void copyProperties(Object source, Object target) {
        List<String> ignoreProperties = findNullFields(source);
        log.debug("null fields: {}, don't copy", ignoreProperties);
        BeanUtils.copyProperties(source, target, ignoreProperties.toArray(new String[0]));
    }

    public static <T> T copyPropertiesClass(Object source, Class<T> clazz) {
        List<String> ignoreProperties = findNullFields(source);
        log.debug("null fields: {}, don't copy", ignoreProperties);
        T target = null;
        try {
            target = clazz.newInstance();
            BeanUtils.copyProperties(source, target, ignoreProperties.toArray(new String[0]));
            return target;
        } catch (InstantiationException | IllegalAccessException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException("copy properties error");
        }
    }

    public static <T, S> List<T> copyListPropertiesClass(List<S> sources, Class<T> clazz){
        if(CollectionUtils.isEmpty(sources)){
            return new ArrayList<>();
        }
        List<T> retList = new ArrayList<>();
        sources.forEach(item -> retList.add(copyPropertiesClass(item, clazz)));
        return retList;
    }

    public static <T> Map<String, Object> parse(T t) {
        Map<String, Object> map = new HashMap<>(16);
        Class<?> clazz = t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String name = field.getName();
            try {
                map.put(name, field.get(t));
            } catch (IllegalAccessException e) {
                log.error(e.getMessage(), e);
            }
        }
        return map;
    }

    /**
     * 获取所有空列
     *
     * @param source 源对象
     * @return java.util.List<java.lang.String>
     * @author ushier@yeah.net
     * @date 2021/12/5 11:08
     */
    private static List<String> findNullFields(Object source) {
        List<Field> fieldList = new ArrayList<>();
        Class<?> clazz = source.getClass();
        Field[] fields = clazz.getDeclaredFields();
        if (fields.length > 0) {
            fieldList.addAll(Arrays.asList(fields));
        }
        appendSuperClassFields(clazz, fieldList);
        List<String> retList = new ArrayList<>();
        for (Field field : fieldList) {
            field.setAccessible(true);
            try {
                Object val = field.get(source);
                if (null == val) {
                    retList.add(field.getName());
                }
            } catch (IllegalAccessException e) {
                log.error(e.getMessage(), e);
            }
        }
        return retList;
    }

    /**
     * 检测某类是否有某字段
     *
     * @param clazz       某类
     * @param searchField 查找的列
     * @return boolean      是否存在此字段
     */
    public static <T> boolean hasField(Class<T> clazz, String searchField) {
        List<Field> fieldList = new ArrayList<>();
        Field[] fields = clazz.getDeclaredFields();
        if (fields.length > 0) {
            fieldList.addAll(Arrays.asList(fields));
        }
        appendSuperClassFields(clazz, fieldList);
        for (Field field : fieldList) {
            if (field.getName().equals(searchField)) {
                return true;
            }
        }
        return false;
    }

    private static <T> void appendSuperClassFields(Class<T> clazz, List<Field> fieldList) {
        if (null != clazz) {
            Class<? super T> superclass = clazz.getSuperclass();
            if (null != superclass) {
                Field[] fields = superclass.getDeclaredFields();
                if (fields.length > 0) {
                    fieldList.addAll(Arrays.asList(fields));
                }
                appendSuperClassFields(superclass.getSuperclass(), fieldList);
            }
        }
    }
}
